﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Transactions;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using XRM.Security.DataAccess.Enums;
using XRM.Security.DataAccess.Helpers;
using XRM.Security.DataAccess.Models;
using XRM.Security.WebUI.Enums;
using XRM.Security.WebUI.Helpers;
using XRM.Security.WebUI.Models;
using XRM.Security.WebUI.Models.CertRegister;
using XRM.Security.WebUI.Models.Request;
using XRM.Security.WebUI.Models.Template;
using XRM.Security.WebUI.Models.UserRegister;
using XRM.Sag.Utils.Helpers;
using XRM.Security.WebUI.Models.WorkKind;
using XRM.Security.WebUI.Models.InfoSystem;

namespace XRM.Security.WebUI.Controllers
{
    [System.Web.Mvc.Authorize]
    public class RequestController : BaseController
    {
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult Index(string text, bool? showAll)
        {
            var requests = RequestRepository.GetAll(x => !x.Status.Equals((int)RequestStatus.Error));
            if (!string.IsNullOrEmpty(text))
                requests = requests.Where(x => (x.UserRegister.LastName + " " + x.UserRegister.FirstName + " " + x.UserRegister.MotherName).Replace("ё", "е").Contains(text.Replace("ё", "е")) ||
                    x.UserRegister.Department.Name.Replace("ё", "е").Contains(text.Replace("ё", "е")));
            if ((!showAll.HasValue) || (!showAll.Value))
                requests = requests.OpenRequests();
            requests = requests.OrderByDescending(x => x.Number);
            var model = new RequestSearchModel
            {
                TextFilter = text,
                ShowAllFilter = showAll.HasValue && showAll.Value,
                RequestList = requests.Select( s => new RequestSearchItem
                    {
                        Id = s.RequestId,
                        CloseDate    = s.CloseDate,
                        CreateDate = s.CreateDate,
                        Deadline = s.DeadLine,
                        Department = s.UserRegister.Department.Name,
                        DepartmentAddress = s.UserRegister.DepartmentAddress.Address,
                        Number = s.Number,
                        Status = (RequestStatus)s.Status,
                        UserId = s.UserRegisterId,
                        UserLastName = s.UserRegister.LastName,
                        UserFirstName = s.UserRegister.FirstName,
                        UserMiddleName = s.UserRegister.MotherName,
                        WorkKinds = s.RequestWorkKinds.Select( g => g.WorkKind.WorkKindName ).ToList()
                    }).ToList()
            };
            return View(model);
        }

        [System.Web.Mvc.HttpPost]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult Filter(UserRegisterListModel model)
        {
            if (!ModelState.IsValid)
            {
                ShowAlert(AlertType.Error, GetModelErrors());
                return View("Index", model);
            }

            return RedirectToAction("Index", new { text = model.TextFilter, showAll = model.ShowAllFilter });
        }

        [System.Web.Mvc.HttpGet]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult Edit(int? id, int? userId)
        {
            string filePath = Path.Combine(FilesFolder, "CertRegister", "New", Session.SessionID);
            Utils.CreateOrClearDirectory(filePath);
            Session["RequestWorkKindState"] = null;

            RequestModel model;
            if (id != null)
            {
                var request = RequestRepository.Get( id );
                if (request == null)
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                model = new RequestModel(request);
            }
            else
            {
                model = new RequestModel();
                if (userId.HasValue)
                {
                    var userRegister = UserRegisterRepository.Get( userId.Value );
                    model.UserRegisterId = userId;
                    model.UserRegisterName = userRegister.FullName();
                    model.RedirectToUserPage = true;
                }
            }
            
            model.GetWorkKindAll(WorkKindRepository.GetAll().OrderBy(x => x.WorkKindName).ToList());
            model.GetSystemUserAll(SystemUserRepository.GetAll().ToList());
            
            if (!model.IsEdit)
            {
                Session["SystemUserId"] = UserPrincipal.UserId;
                model.SystemUserId = UserPrincipal.UserId;
            }

            return View(model);
        }

        [System.Web.Mvc.HttpGet]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult PrintRequest(int requestId, PrintFormType type, int? requestWorkKindId = null)
        {
            var documentTemplate = RequestRepository.Get(requestId);
            if (documentTemplate == null)
                throw new HttpResponseException(HttpStatusCode.BadRequest);
            RequestWorkKind requestWorkKind = null;

            if (type == PrintFormType.ActIntroducingSCSI || type == PrintFormType.ActSettingSCSI)
            {
                  requestWorkKind =
                    documentTemplate.RequestWorkKinds.FirstOrDefault(x => x.RequestWorkKindId == requestWorkKindId);
                  if (requestWorkKind == null)
                      throw new HttpResponseException(HttpStatusCode.BadRequest);
            }

            var word = documentTemplate.GenerateFileFromTemplateDocument(type, requestWorkKind);
            return File(word.ToByteArray(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document", String.Format("{0} № {1}.docx", EnumHelper.Description(type), documentTemplate.Number));
        }
         
         [System.Web.Mvc.HttpGet]
         [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult SelectWorkKind(int requestId, PrintFormType type)
        {
            var documentTemplate = RequestRepository.Get(requestId);
            if (documentTemplate == null)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            var model = new PrintFormModel
            {
                RequestWorkKind = documentTemplate.RequestWorkKinds.Where(x =>
                    x.WorkKind.WorkKindId == (int)WorkKindCode.ScsiNewUser
                    || x.WorkKind.WorkKindId == (int)WorkKindCode.ScsiNewPC).ToList(),
                PrintFormType = type,
                RequestId = requestId
            };
            return View("SelectWorkKindDialog" , model);
        }

        [System.Web.Mvc.HttpPost]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult Edit(RequestModel model)
        {
            Session["RequestWorkKindState"] = null;
            model.GetWorkKindAll(WorkKindRepository.GetAll().OrderBy(x => x.WorkKindName).ToList());
            model.GetSystemUserAll(SystemUserRepository.GetAll().ToList());
            foreach (var item in model.WorkKindList)
            {
                item.GetWorkKind(WorkKindRepository.Get(item.WorkKindId));
                if (model.Id.HasValue)
                    item.RequestId = model.Id.Value;
            }

            if (!ModelState.IsValid)
            {
                Session["RequestWorkKindState"] = model.WorkKindList;
                return View(model);
            }

            Request dbItem;
            var checkUser = false;
            if (model.IsEdit)
            {
                dbItem = RequestRepository.Get( model.Id );
                if (dbItem == null)
                    throw new HttpResponseException(HttpStatusCode.BadRequest);
                if (dbItem.UserRegisterId != model.UserRegisterId)
                {
                    checkUser = true;
                }
            }
            else
            {
                dbItem = new Request();
                checkUser = true;
            }

            if ( checkUser )
            {
                var user = UserRegisterRepository.Get( model.UserRegisterId );
                if ( user == null )
                {
                    throw new HttpResponseException( HttpStatusCode.BadRequest );
                }
                if ( user.Status != (int)UserStatus.Work )
                {
                    Session["RequestWorkKindState"] = model.WorkKindList;
                    ModelState.AddModelError( "UserRegisterId", "Пользователь должен иметь статус 'Работающий'" );
                    return View( model );
                }
            }

            if ( model.DeadLine != null && dbItem.DeadLine != model.DeadLine && model.DeadLine < DateTime.Today )
            {
                Session["RequestWorkKindState"] = model.WorkKindList;
                ModelState.AddModelError( "DeadLine", "Крайний срок не может быть раньше текущей даты" );
                return View(model);
            }

            // Разбор сертификатов
            string certErrorParam = "";
            string certError = "";
            foreach (RequestWorkKindModel item in model.WorkKindList)
            {
                foreach (RequestWorkKindParamModel itemSub in item.WorkKindParamList)
                {
                    itemSub.GetWorkKindParam(WorkKindParamRepository.Get(itemSub.WorkKindParamId));
                    if (itemSub.WorkKindParam.CustomId == (int)WorkKindParamCode.Cert)
                    {
                        if ((!itemSub.RequestCertId.HasValue) || (itemSub.RequestCertId.Value <= 0))
                        {
                            int requestCertId = ParseRequestCert(model.UserRegisterId.Value, itemSub, out certErrorParam);
                            if (string.IsNullOrEmpty(certErrorParam) && (requestCertId > 0))
                                itemSub.RequestCertId = requestCertId;
                            else if (!string.IsNullOrEmpty(certErrorParam))
                                certError += certErrorParam;
                        }
                    }
                    /*else if (itemSub.WorkKindParam.CustomId == (int)WorkKindParamCode.SerialNumberAdd)
                    {
                        if ((!string.IsNullOrEmpty(itemSub.SerialNumber)) && (!string.IsNullOrEmpty(itemSub.PCHost)))
                        {
                            if (UserPCRepository.GetAll(x => x.UserRegisterId == model.UserRegisterId.Value && x.PC.SerialNumber == itemSub.SerialNumber).Any())
                            {
                                ShowAlert(AlertType.Error, string.Format("ПК с серийным номером '{0}' уже существует", itemSub.SerialNumber));
                                Session["RequestWorkKindState"] = model.WorkKindList;
                                return View(model);
                            }

                            if (UserPCRepository.GetAll(x => x.UserRegisterId == model.UserRegisterId.Value && x.PC.PCHost == itemSub.PCHost).Any())
                            {
                                ShowAlert(AlertType.Error, string.Format("ПК с hostname '{0}' уже существует", itemSub.PCHost));
                                Session["RequestWorkKindState"] = model.WorkKindList;
                                return View(model);
                            }
                        }
                    }*/
                }
            }

            if (!string.IsNullOrEmpty(certError))
            {
                Session["RequestWorkKindState"] = model.WorkKindList;
                ShowAlert(AlertType.Error, certError);
                return View(model);
            }
            
            if (!model.IsEdit)
            {
                dbItem.Status = (int)RequestStatus.InWork;
                dbItem.CreateDate = DateTime.Now;
                dbItem.Number = model.Number;
            }
            else
            {
                List<RequestWorkKind> listWorkKinds = RequestWorkKindRepository.GetAll(x => x.RequestId == model.Id && !x.CloseDate.HasValue).ToList();
                foreach (RequestWorkKind item in listWorkKinds)
                {
                    if (!model.WorkKindList.Where(x => x.Id.HasValue && x.Id.Value == item.RequestWorkKindId).Any())
                        RequestWorkKindRepository.Delete(RequestWorkKindRepository.Get(item.RequestWorkKindId));
                    RequestWorkKindParamRepository.GetAll(x => x.RequestWorkKind.Request.RequestId == model.Id.Value && !x.RequestWorkKind.CloseDate.HasValue).ToList().ForEach(x => RequestWorkKindParamRepository.Delete(x));
                }
            }

            dbItem.DeadLine = model.DeadLine;
            dbItem.SystemUserId = model.SystemUserId;
            dbItem.UserRegisterId = model.UserRegisterId.Value;
            dbItem.Comment = model.Comment;

            foreach (RequestWorkKindModel item in model.WorkKindList)
            {
                if ((item.Id.HasValue) && (dbItem.RequestWorkKinds.Where(x => x.RequestWorkKindId == item.Id.Value && x.CloseDate.HasValue).Any()))
                    continue;

                RequestWorkKind dbItemWorkKind;
                if ((item.Id.HasValue) && (item.Id.Value > 0))
                {
                    dbItemWorkKind = dbItem.RequestWorkKinds.Where(x => x.RequestWorkKindId == item.Id.Value).Single();
                    dbItemWorkKind.RequestWorkKindParams.Clear();
                }
                else
                {
                    dbItemWorkKind = new RequestWorkKind();
                    dbItem.RequestWorkKinds.Add(dbItemWorkKind);
                }

                dbItemWorkKind.WorkKindId = item.WorkKindId;

                // Вид работы "Выпуск сертификата"
                // При загрузке сертификата статус готовности автоматически принимает значение "Сертификат установлен" и работа закрывается
                if (item.WorkKind.CustomId == (int)WorkKindCode.CertCreate)
                {
                    RequestWorkKindParamModel pCert = item.WorkKindParamList.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.Cert && x.RequestCertId.HasValue && x.RequestCertId > 0).SingleOrDefault();
                    if (pCert != null)
                    {
                        item.WorkKindParamList.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.StatusDoc).ToList().ForEach(x => x.ParamValue = ((int)DocStatus.Installed).ToString());
                    }
                }

                foreach (RequestWorkKindParamModel itemSub in item.WorkKindParamList)
                {
                    RequestWorkKindParam dbItemWorkKindParam = new RequestWorkKindParam();

                    if ((itemSub.DepartmentAddressId.HasValue) && (itemSub.DepartmentAddressId.Value > 0))
                        dbItemWorkKindParam.DepartmentAddressId = itemSub.DepartmentAddressId;
                    if ((itemSub.DepartmentId.HasValue) && (itemSub.DepartmentId.Value > 0))
                        dbItemWorkKindParam.DepartmentId = itemSub.DepartmentId;
                    if ((itemSub.InfoSystemId.HasValue) && (itemSub.InfoSystemId.Value > 0))
                        dbItemWorkKindParam.InfoSystemId = itemSub.InfoSystemId;
                    if ((itemSub.PCId.HasValue) && (itemSub.PCId.Value > 0))
                        dbItemWorkKindParam.PCId = itemSub.PCId;
                    if ((itemSub.SkziKindId.HasValue) && (itemSub.SkziKindId.Value > 0))
                        dbItemWorkKindParam.SkziKindId = itemSub.SkziKindId;
                    if ((itemSub.RequestCertId.HasValue) && (itemSub.RequestCertId.Value > 0))
                        dbItemWorkKindParam.RequestCertId = itemSub.RequestCertId;
                    
                    if ((itemSub.WorkKindParam.CustomId == (int)WorkKindParamCode.LastName)
                        || (itemSub.WorkKindParam.CustomId == (int)WorkKindParamCode.FirstName)
                            || (itemSub.WorkKindParam.CustomId == (int)WorkKindParamCode.MotherName))
                        itemSub.ParamValue = Utils.FirstLetterToUpper(itemSub.ParamValue);
                    dbItemWorkKindParam.ParamValue = itemSub.ParamValue;
                    dbItemWorkKindParam.ParamValue1 = itemSub.ParamValue1;
                    dbItemWorkKindParam.WorkKindParamId = itemSub.WorkKindParamId;
                    
                    foreach (RequestWorkKindParamSpecModel itemSpec in itemSub.WorkKindParamSpecList)
                    {
                        RequestWorkKindParamSpec dbItemWorkKindParamSpec = new RequestWorkKindParamSpec();
                        dbItemWorkKindParamSpec.ParamValue = itemSpec.ParamValue;
                        dbItemWorkKindParam.RequestWorkKindParamSpecs.Add(dbItemWorkKindParamSpec);
                    }


                    dbItemWorkKind.RequestWorkKindParams.Add(dbItemWorkKindParam);
                }
               

            }

            if (model.IsEdit)
            {
                if (!dbItem.RequestWorkKinds.Where(x => !x.CloseDate.HasValue).Any())
                {
                    dbItem.Status = (int)RequestStatus.Closed;
                    dbItem.CloseDate = dbItem.RequestWorkKinds.Max(x => x.CloseDate.Value);
                }
                RequestRepository.Update(dbItem);
                ShowAlert(AlertType.Success, "Заявка обновлена успешно");
            }
            else
            {
                using ( var scope = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }) )
                {
                    dbItem.Number = RequestRepository.GetNewRequestNumber();
                    RequestRepository.Add( dbItem );
                    scope.Complete();
                }
                ShowAlert(AlertType.Success, String.Format("Заявка успешно создана. Номер заявки: {0}.", dbItem.Number));
            }

            if ((string.IsNullOrEmpty(model.SubmitAction)) || (model.SubmitAction == "save"))
                return model.RedirectToUserPage ? RedirectToAction("Edit", "USerRegister", new { id = model.UserRegisterId }) : RedirectToAction("Index");
            else
            {
                if (model.SubmitAction == "closeRequest")
                    TempData["CloseRequest"] = 1;
                else if (model.SubmitAction == "closeWorkKind")
                    TempData["CloseWorkKind"] = 1;

                int closeId = model.WorkKindIdClose;

                model = new RequestModel(dbItem);
                model.GetWorkKindAll(WorkKindRepository.GetAll().OrderBy(x => x.WorkKindName).ToList());
                model.GetSystemUserAll(SystemUserRepository.GetAll().ToList());
                model.WorkKindIdClose = closeId;
                foreach (RequestWorkKindModel item in model.WorkKindList)
                {
                    if (!item.WorkKind.Id.HasValue)
                        item.WorkKind = new WorkKindModel(WorkKindRepository.Get(item.WorkKindId), null);
                }

                return View(model);
            }

            //return model.RedirectToUserPage ? RedirectToAction("Edit", "UserRegister", new { id = model.UserRegisterId }) : RedirectToAction("Index");
        }

        [System.Web.Mvc.NonAction]
        public int ParseRequestCert(int userRegisterId, RequestWorkKindParamModel param, out string certError)
        {
            int result = 0;
            certError = "";

            if (string.IsNullOrEmpty(param.DataId))
                return result;
            
            var certData = Session[param.DataId] as UploadCertTempData;
            bool fileError = false;
            RequestCert fileModel = new RequestCert();

            try
            {
                fileError = false;

                if (certData == null)
                {
                    fileError = true;
                    certError = "Ошибка чтения сертификата";
                }

                if (!fileError)
                {
                    X509Certificate2 cert = certData.UserCertificate;
                    fileModel.SetProperties(cert, certData.FileName);
                                        
                    var issuerName = cert.GetIssuerOrganizationName();
                    IdentityCenter ic = CertRegisterRepository.GetIdentityCenter(issuerName);
                    if (ic == null)
                    {
                        ic = new IdentityCenter();
                        ic.IdentityCenterName = issuerName;
                        IdentityCenterRepository.Add(ic);
                    }

                    ic.IsDeleted = false;
                    if ((certData.RootCertificate != null) && (ic.Files.SingleOrDefault(x => x.Thumbprint.Equals(certData.RootCertificate.Thumbprint)) == null))
                    {
                        var identityCenterCertificate = new IdentityCenterCert();
                        identityCenterCertificate.SetProperties(certData.RootCertificate, certData.FileName);
                        ic.Files.Add(identityCenterCertificate);
                        IdentityCenterRepository.Update(ic);
                    }
                    fileModel.IdentityCenterId = ic.IdentityCenterId;

                    string nameUser = cert.GetUserName();
                    if (!UserRegisterRepository.GetUsersByFio(nameUser).Where(x => x.UserRegisterId == userRegisterId).Any())
                    {
                        certError += string.Format("Сертификат: {0}, в сертификате указан другой пользователь {1}<br/>", certData.FileName, nameUser);
                        fileError = true;
                    }
                    else
                    {
                        fileModel.UserRegisterId = userRegisterId;
                    }
                }

                if (fileError)
                {
                }
                else
                {
                    RequestCertRepository.Add(fileModel);
                    result = fileModel.RequestCertId;
                }
            }
            catch (Exception ex)
            {
                fileError = true;
            }

            return result;
        }

        [System.Web.Mvc.HttpGet]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult CertDialog(int id)
        {
            var model = new RequestCertModel(RequestCertRepository.Get(id));
            return View(model);
        }

        [System.Web.Mvc.HttpPost]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult CertDialog( RequestCertModel model )
        {
            for (int i = 0; i < model.InfoSystemList.Count; ++i)
            {
                ModelState["InfoSystemList[" + i.ToString() + "].InfoSystemName"].Errors.Clear();
            }

            model.InfoSystemList = model.InfoSystemList.Where(x => x.Id > 0).ToList();
            foreach(InfoSystemModel item in model.InfoSystemList)
            {
                item.InfoSystemName = InfoSystemRepository.Get(item.Id).InfoSystemName;
            }
            model.GetCertUser(UserRegisterRepository.Get(model.UserRegisterId));
            model.GetIdentityCenter(IdentityCenterRepository.Get(model.IdentityCenterId));
            
            if ( !ModelState.IsValid )
            {
                ShowAlert( AlertType.Error, GetModelErrors() );
                return View( model );
            }

            ModelState.Clear();
            
            if (model.UserRegisterId <= 0)
            {
                ShowAlert(AlertType.Error, "Поле 'Пользователь' обязательное");
                return View(model);
            }

            if (model.InfoSystemList.Select(x => x.InfoSystemName).Distinct().Count() != model.InfoSystemList.Count())
            {
                ShowAlert(AlertType.Error, "Информационные системы не уникальны");
                return View(model);
            }
            
            RequestCert certRegister = RequestCertRepository.Get(model.Id);
            certRegister.RequestCertInfoSystems.Clear();
            RequestCertRepository.Update(certRegister);
            
            certRegister.SerialNumberEtoken = model.SerialNumberEtoken;
            certRegister.PCId = model.PCId > 0 ? model.PCId : null;

            List<RequestCertInfoSystem> RequestCertInfoSystems = model.InfoSystemList.Select(x => new RequestCertInfoSystem { RequestCertId = certRegister.RequestCertId, InfoSystemId = x.Id.Value }).ToList();
            foreach (RequestCertInfoSystem item in RequestCertInfoSystems)
            {
                certRegister.RequestCertInfoSystems.Add(item);
            }
            certRegister.UserRegisterId = model.UserRegisterId;
            
            RequestCertRepository.Update(certRegister);
            TempData["RequestCertId"] = certRegister.RequestCertId;
            return Json(new { success = true });
        }

        [System.Web.Mvc.HttpPost]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public JsonResult GetSelectedCert()
        {
            int result = -1;
            if (TempData["RequestCertId"] != null)
                result = (int)TempData["RequestCertId"];
            return Json(result, JsonRequestBehavior.AllowGet);
        }

        [System.Web.Mvc.HttpPost]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public JsonResult DeleteRequestCert(int id)
        {
            RequestWorkKindParam param = RequestWorkKindParamRepository.Get(id);
            if (param.RequestCertId.HasValue)
            {
                int requestCertId = param.RequestCertId.Value;

                param.RequestCertId = null;
                RequestWorkKindParamRepository.Update(param);

                RequestCert cert = RequestCertRepository.Get(requestCertId);
                if (cert != null)
                {
                    RequestCertRepository.Delete(cert);
                }
            }

            int result = 1;
            return Json(result, JsonRequestBehavior.AllowGet);
        }

        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult CertTable(int id, string baseName)
        {
            RequestCert cert = RequestCertRepository.Get(id);
            var model = new CertRegisterModel(cert);
            ViewData["BaseName"] = baseName;
            return PartialView("CertTable", model);
        }

        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult GetWorkKindParamView(int id, int uId, int wkId, string contId)
        {
            ViewData["FileUploadUrl"] = Url.Action("UploadFiles");

            int itemIndex = Convert.ToInt32(contId.Substring(11));
            RequestWorkKindModel model = null;
            if (id > 0)
            {
                RequestWorkKind dbItem = RequestWorkKindRepository.Get(id);
                if ((dbItem != null) && (dbItem.WorkKindId == wkId))
                    model = new RequestWorkKindModel(dbItem);
            }

            if (model == null)
            {
                model = new RequestWorkKindModel(WorkKindRepository.Get(wkId));
            }

            if (Session["RequestWorkKindState"] != null)
            {
                List<RequestWorkKindModel> modelStateList = (List<RequestWorkKindModel>)Session["RequestWorkKindState"];
                if (itemIndex < modelStateList.Count)
                {
                    RequestWorkKindModel modelState = modelStateList[itemIndex];
                    if (modelState != null)
                    {
                        for (int i = 0; i < modelState.WorkKindParamList.Count; ++i)
                        {
                            model.WorkKindParamList[i].DepartmentId = modelState.WorkKindParamList[i].DepartmentId;
                            model.WorkKindParamList[i].DepartmentAddressId = modelState.WorkKindParamList[i].DepartmentAddressId;
                            model.WorkKindParamList[i].InfoSystemId = modelState.WorkKindParamList[i].InfoSystemId;
                            model.WorkKindParamList[i].ParamValue = modelState.WorkKindParamList[i].ParamValue;
                            model.WorkKindParamList[i].ParamValue1 = modelState.WorkKindParamList[i].ParamValue1;
                            model.WorkKindParamList[i].PCId = modelState.WorkKindParamList[i].PCId;
                            model.WorkKindParamList[i].SkziKindId = modelState.WorkKindParamList[i].SkziKindId;
                            
                            //model.WorkKindParamList[i].Cert = modelState.WorkKindParamList[i].Cert;
                        }
                        model.RequestId = modelState.RequestId;
                        model.Id = modelState.Id;
                        
                        modelStateList[itemIndex] = null;
                    }
                }
                if (!modelStateList.Any(x => x != null))
                    Session.Remove("RequestWorkKindState");
            }


            model.WorkKindIndex = itemIndex;
            model.WorkKindContId = contId;

            model.GetDepartmentAll(DepartmentRepository.GetAll().OrderBy(x => x.Name).ToList());
            model.GetSkziKindAll(SkziKindRepository.GetAll().OrderBy(x => x.ShortName).ToList());

            model.UserRegisterId = uId;
            model.GetPCUser(UserPCRepository.GetPCByUserId(uId).OrderBy(x => x.SerialNumber).ToList());
            //model.GetInfoSystemUser(dbUser.InfoSystems.Where(x => !x.RevokeDate.HasValue).OrderBy(x => x.InfoSystem.InfoSystemName).ToList());
            //model.GetInfoSystemUser(InfoSystemRepository.GetAll(x => x.InMaintenance).OrderBy(x => x.InfoSystemName).ToList());
            model.GetInfoSystemUser(InfoSystemRepository.GetAll().OrderBy(x => x.InfoSystemName).ToList());

            return PartialView("WorkKindParams", model);
        }

        [System.Web.Mvc.HttpGet]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public FileStreamResult DownloadCert(int id)
        {
            RequestCert certRegister = RequestCertRepository.Get(id);

            if (certRegister != null)
            {
                Stream fileStream = new MemoryStream(certRegister.FileData);
                FileStreamResult fsr = new FileStreamResult(fileStream, "application/octet-stream");
                fsr.FileDownloadName = Path.GetFileName(certRegister.FileName);
                return fsr;
            }
            else
                return null;
        }

        [System.Web.Mvc.HttpGet]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult CancelDialog(int requestId)
        {
            var model = new RequestCancelModel {
                    RequestId = requestId,
                    CancelDate = DateTime.Today
            };
            return View(model);
        }

        [System.Web.Mvc.HttpPost]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult CancelDialog(RequestCancelModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }

            var dbItem = RequestRepository.Get(model.RequestId);
            if (model.CancelDate < dbItem.CreateDate.Date)
            {
                ModelState.AddModelError("CancelDate", "Дата отмены не может быть раньше даты создания заявки");
                return View(model);
            }

            dbItem.CloseDate = model.CancelDate;
            dbItem.Status = (int)RequestStatus.Error;
            RequestRepository.Update(dbItem);

            return Json(new { success = true });
        }

        [System.Web.Mvc.HttpGet]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult CloseDialog(int? requestId, int? requestWorkKindId)
        {
            var model = new RequestCloseModel {
                    RequestId = requestId,
                    RequestWorkKindId = requestWorkKindId,
                    CloseDate = DateTime.Today
            };
            return View(model);
        }

        [System.Web.Mvc.HttpPost]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public ActionResult CloseDialog(RequestCloseModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }

            Request dbItem1 = null;
            RequestWorkKind dbItem2 = null;

            if (model.RequestId.HasValue)
            {
                dbItem1 = RequestRepository.Get(model.RequestId);
                if (model.CloseDate < dbItem1.CreateDate.Date)
                {
                    ModelState.AddModelError("CloseDate", "Дата закрытия не может быть меньше даты создания заявки");
                    return View(model);
                }
            }
            else
            {
                dbItem2 = RequestWorkKindRepository.Get(model.RequestWorkKindId);
                if ( model.CloseDate < dbItem2.Request.CreateDate.Date )
                {
                    ModelState.AddModelError( "CloseDate", "Дата закрытия не может быть меньше даты создания заявки" );
                    return View(model);
                }
            }

            List<RequestWorkKind> works = new List<RequestWorkKind>();
            if (dbItem1 != null)
                works.AddRange(dbItem1.RequestWorkKinds.Where(x => !x.CloseDate.HasValue).ToList());
            if (dbItem2 != null)
                works.Add(dbItem2);

            int[] simpleTextCode = { (int)WorkKindParamCode.Comment, (int)WorkKindParamCode.Hostname, (int)WorkKindParamCode.CopyNumber, 
                                       (int)WorkKindParamCode.LastName, (int)WorkKindParamCode.FirstName, (int)WorkKindParamCode.MotherName, 
                                       (int)WorkKindParamCode.Post, (int)WorkKindParamCode.DeleteReason, (int)WorkKindParamCode.StatusDoc };

            // Проверяем заполненность и корректность параметров
            foreach (RequestWorkKind item in works)
            {
                string paramError = "Для вида работ '" + item.WorkKind.WorkKindName + "' необходимо указать параметр '{0}'";
                string paramError1 = "Для вида работ '" + item.WorkKind.WorkKindName + "', {0}";
                foreach(RequestWorkKindParam itemParam in item.RequestWorkKindParams)
                {
                    int customId = itemParam.WorkKindParam.CustomId;
                    
                    if (simpleTextCode.Contains(customId))
                    {
                        if (string.IsNullOrEmpty(itemParam.ParamValue))
                        {
                            ShowAlert(AlertType.Error, string.Format(paramError, itemParam.WorkKindParam.WorkKindParamName));
                            return View(model);
                        }
                    }
                    else if (customId == (int)WorkKindParamCode.Department)
                    {
                        if ((!itemParam.DepartmentId.HasValue) || (!itemParam.DepartmentAddressId.HasValue))
                        {
                            ShowAlert(AlertType.Error, string.Format(paramError, itemParam.WorkKindParam.WorkKindParamName));
                            return View(model);
                        }
                    }
                    else if (customId == (int)WorkKindParamCode.SkziKind)
                    {
                        if (!itemParam.SkziKindId.HasValue)
                        {
                            ShowAlert(AlertType.Error, string.Format(paramError, itemParam.WorkKindParam.WorkKindParamName));
                            return View(model);
                        }
                    }
                    else if (customId == (int)WorkKindParamCode.SerialNumberAdd)
                    {
                        if (string.IsNullOrEmpty(itemParam.ParamValue))
                        {
                            ShowAlert(AlertType.Error, string.Format(paramError, "серийный номер"));
                            return View(model);
                        }
                        if (string.IsNullOrEmpty(itemParam.ParamValue1))
                        {
                            ShowAlert(AlertType.Error, string.Format(paramError, "hostname"));
                            return View(model);
                        }
                    }
                    else if (customId == (int)WorkKindParamCode.SerialNumberExists)
                    {
                        if (!itemParam.PCId.HasValue)
                        {
                            ShowAlert(AlertType.Error, string.Format(paramError, itemParam.WorkKindParam.WorkKindParamName));
                            return View(model);
                        }
                    }
                    else if (customId == (int)WorkKindParamCode.InfoSystem)
                    {
                        if (!itemParam.InfoSystemId.HasValue)
                        {
                            ShowAlert(AlertType.Error, string.Format(paramError, itemParam.WorkKindParam.WorkKindParamName));
                            return View(model);
                        }
                    }
                    else if (customId == (int)WorkKindParamCode.StickerNumber)
                    {
                        if (!itemParam.RequestWorkKindParamSpecs.Any())
                        {
                            ShowAlert(AlertType.Error, string.Format(paramError, itemParam.WorkKindParam.WorkKindParamName));
                            return View(model);
                        }
                    }
                    else if (customId == (int)WorkKindParamCode.Cert)
                    {
                        if (!itemParam.RequestCertId.HasValue)
                        {
                            ShowAlert(AlertType.Error, string.Format(paramError, itemParam.WorkKindParam.WorkKindParamName));
                            return View(model);
                        }
                    }
                }

                // Предоставить доступ к ИС
                if (item.WorkKind.CustomId == (int)WorkKindCode.GrantInfoSystem)
                {
                    int isId = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.InfoSystem).Single().InfoSystemId.Value;
                    if (UserInfoSystemRepository.GetAll(x => x.UserRegisterId == item.Request.UserRegisterId && x.InfoSystemId == isId && !x.RevokeDate.HasValue).ToList().Any())
                    {
                        ShowAlert(AlertType.Error, string.Format(paramError1, "пользователю уже предоставлен доступ к данной информационной системе"));
                        return View(model);
                    }
                }
                // Установка СЗИ и прикладного ПО по новому пользователю
                // Установка СЗИ при замене ПК
                // Переопечатывание системного блока
                else if ((item.WorkKind.CustomId == (int)WorkKindCode.ScsiNewUser) || (item.WorkKind.CustomId == (int)WorkKindCode.ScsiNewPC) || (item.WorkKind.CustomId == (int)WorkKindCode.ReSticker))
                {
                    if ((item.WorkKind.CustomId == (int)WorkKindCode.ScsiNewUser) || (item.WorkKind.CustomId == (int)WorkKindCode.ScsiNewPC))
                    {
                        // Проверка, что ПК не привязан к другому пользователю
                        string serialNumber = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.SerialNumberAdd).Single().ParamValue;
                        UserPC existsPC = UserPCRepository.Get(x => x.PC.SerialNumber == serialNumber && x.UserRegisterId != item.Request.UserRegisterId);
                        if (existsPC != null)
                        {
                            ShowAlert(AlertType.Error, string.Format(paramError1, "ПК уже установлен пользователю '" + existsPC.UserRegister.FullName() + "'"));
                            return View(model);                       
                        }

                        // Проверка наличия скзи-номера
                        string copyNumber = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.CopyNumber).Single().ParamValue;
                        int skziKindId = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.SkziKind).Single().SkziKindId.Value;

                        UserSkzi existsSkzi = UserSkziRepository.Get(x => x.SkziKindId == skziKindId && x.CopyNumber == copyNumber && !x.DeleteDate.HasValue);
                        if (existsSkzi != null)
                        {
                            ShowAlert(AlertType.Error, string.Format(paramError1, "вид СКЗИ и номер экземпляра уже установлены пользователю '" + existsSkzi.UserRegister.FullName() + "'"));
                            return View(model);
                        }
                    }

                    // Проверка наличия номера наклейки
                    if (item.WorkKind.CustomId == (int)WorkKindCode.ReSticker)
                    {
                        int pcId;
                        pcId = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.SerialNumberExists).Single().PCId.Value;

                        RequestWorkKindParam stickers = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.StickerNumber).Single();
                        if (stickers.RequestWorkKindParamSpecs.Select(x => x.ParamValue).Distinct().Count() != stickers.RequestWorkKindParamSpecs.Select(x => x.ParamValue).Count())
                        {
                            ShowAlert(AlertType.Error, string.Format(paramError1, "номера наклеек не уникальны"));
                            return View(model);
                        }

                        foreach (RequestWorkKindParamSpec spec in stickers.RequestWorkKindParamSpecs)
                        {
                            if (PCStickerRepository.GetAll(x => x.PCId == pcId && x.StickerNumber == spec.ParamValue).ToList().Any())
                            {
                                ShowAlert(AlertType.Error, string.Format(paramError1, "номер наклейки " + spec.ParamValue + " уже внесен для ПК"));
                                return View(model);
                            }
                        }
                    }
                }
                // Удаление СЗИ в связи с увольнением/декретом
                else if (item.WorkKind.CustomId == (int)WorkKindCode.ScsiDel)
                {
                    // Проверка наличия СКЗИ и что уже не удален
                    string copyNumber = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.CopyNumber).Single().ParamValue;
                    int skziKindId = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.SkziKind).Single().SkziKindId.Value;
                    if (!UserSkziRepository.GetAll(x => x.SkziKindId == skziKindId && x.CopyNumber == copyNumber && !x.DeleteDate.HasValue).Any())
                    {
                        ShowAlert(AlertType.Error, string.Format(paramError1, "данного экземпляра СКЗИ в карточке пользователя нет, его удаление невозможно"));
                        return View(model);
                    }
                }
                // Установка ЭП
                // Переустановка ЭП по причине истечения срока  действия
                // Регистрация ЭП
                // Выпуск сертификата
                else if ((item.WorkKind.CustomId == (int)WorkKindCode.CertInstall) || (item.WorkKind.CustomId == (int)WorkKindCode.CertReInstall) || (item.WorkKind.CustomId == (int)WorkKindCode.CertRegister) || (item.WorkKind.CustomId == (int)WorkKindCode.CertCreate))
                {
                    // Проверка наличия сертификата
                    int requestCertId = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.Cert).Single().RequestCertId.Value;
                    RequestCert requestCert = RequestCertRepository.Get(requestCertId);
                    if (CertRegisterRepository.GetAll(s => s.Thumbprint == requestCert.Thumbprint).Any())
                    {
                        ShowAlert(AlertType.Error, string.Format(paramError1, "сертификат с отпечатком '" + requestCert.Thumbprint + "' уже был загружен"));
                        return View(model);
                    }
                }
            }
            
            if (dbItem1 != null)
            {
                dbItem1.RequestWorkKinds.Where(x => !x.CloseDate.HasValue).ToList().ForEach(x => x.CloseDate = model.CloseDate);
                dbItem1.Status = (int)RequestStatus.Closed;
                dbItem1.CloseDate = model.CloseDate;
                RequestRepository.Update(dbItem1);
            }
            else if (dbItem2 != null)
            {
                dbItem2.CloseDate = model.CloseDate;
                RequestWorkKindRepository.Update(dbItem2);
                
                dbItem1 = RequestRepository.Get(dbItem2.RequestId);
                int countOpen = dbItem2.Request.RequestWorkKinds.Where(x => !x.CloseDate.HasValue).ToList().Count();
                if ( countOpen > 0 )
                    dbItem1.Status = (int)RequestStatus.InPart;
                else
                {
                    dbItem1.Status = (int)RequestStatus.Closed;
                    dbItem1.CloseDate = model.CloseDate;
                }
                RequestRepository.Update(dbItem1);
            }

            // Делаем изменения по фикс работам
            foreach (RequestWorkKind item in works)
            {
                // Предоставить доступ к ИС
                if (item.WorkKind.CustomId == (int)WorkKindCode.GrantInfoSystem)
                {
                    int isId = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.InfoSystem).Single().InfoSystemId.Value;
                    UserRegister_GrantInfoSystem(item.Request.UserRegisterId, isId, item.RequestId);
                }
                // Актуализация информации в связи со сменой фамилии
                // Актуализация информации в связи с переводом на новую должность/рабочее место
                else if ((item.WorkKind.CustomId == (int)WorkKindCode.LastNameChange) || (item.WorkKind.CustomId == (int)WorkKindCode.PostChange))
                {
                    UserRegister dbItem = UserRegisterRepository.Get(item.Request.UserRegisterId);
                    UserRegisterModel oldUser = new UserRegisterModel(dbItem);
                    UserRegisterModel newUser = new UserRegisterModel(dbItem);

                    if (item.WorkKind.CustomId == (int)WorkKindCode.LastNameChange)
                    {
                        dbItem.LastName = newUser.LastName = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.LastName).Single().ParamValue;
                        dbItem.FirstName = newUser.FirstName = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.FirstName).Single().ParamValue;
                        dbItem.MotherName = newUser.MotherName = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.MotherName).Single().ParamValue;
                    }

                    if (item.WorkKind.CustomId == (int)WorkKindCode.PostChange)
                    {
                        dbItem.Post = newUser.Post = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.Post).Single().ParamValue;
                        dbItem.DepartmentId = newUser.DepartmentId = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.Department).Single().DepartmentId.Value;
                        dbItem.DepartmentAddressId = newUser.DepartmentAddressId = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.Department).Single().DepartmentAddressId.Value;
                    }

                    UserRegisterRepository.Update(dbItem);
                    AddUserHistory(oldUser, newUser, item.RequestId);
                }
                // Установка СЗИ и прикладного ПО по новому пользователю
                // Установка СЗИ при замене ПК
                // Переопечатывание системного блока
                else if ((item.WorkKind.CustomId == (int)WorkKindCode.ScsiNewUser) || (item.WorkKind.CustomId == (int)WorkKindCode.ScsiNewPC) || (item.WorkKind.CustomId == (int)WorkKindCode.ReSticker))
                {
                    int pcId;

                    if ((item.WorkKind.CustomId == (int)WorkKindCode.ScsiNewUser) || (item.WorkKind.CustomId == (int)WorkKindCode.ScsiNewPC))
                    {
                        string serialNumber = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.SerialNumberAdd).Single().ParamValue;
                        string hostName = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.SerialNumberAdd).Single().ParamValue1;

                        PC dbPC = PCRepository.Get(x => x.SerialNumber == serialNumber);
                        if (dbPC == null)
                        {
                            dbPC = new PC();
                            dbPC.SerialNumber = serialNumber;
                            dbPC.PCHost = hostName;
                            PCRepository.Add(dbPC);
                        }

                        UserRegister usr = UserRegisterRepository.Get(item.Request.UserRegisterId);
                        if (!usr.PCs.Where(x => x.PCId.Equals(dbPC.PCId)).ToList().Any())
                        {
                            usr.PCs.Add(new UserPC() { PCId = dbPC.PCId, UserRegisterId = usr.UserRegisterId });
                            UserRegisterRepository.Update(usr);
                            AddUserHistory_AddPC(item.Request.UserRegisterId, dbPC.PCId, null, item.Request.RequestId);
                        }

                        pcId = dbPC.PCId;
                    }
                    else
                        pcId = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.SerialNumberExists).Single().PCId.Value;
                    
                    if ((item.WorkKind.CustomId == (int)WorkKindCode.ScsiNewUser) || (item.WorkKind.CustomId == (int)WorkKindCode.ScsiNewPC))
                    {
                        // Добавим СКЗИ
                        UserSkzi dbItem = new UserSkzi();
                        dbItem.SetupDate = DateTime.Today.Date;
                        dbItem.UserRegisterId = item.Request.UserRegisterId;
                        dbItem.SetupSystemUserId = UserPrincipal.UserId;
                        dbItem.CopyNumber = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.CopyNumber).Single().ParamValue;
                        dbItem.PCId = pcId;
                        dbItem.SkziKindId = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.SkziKind).Single().SkziKindId.Value;
                        UserSkziRepository.Add(dbItem);
                        AddUserHistory_AddScsi(dbItem.UserSkziId, item.RequestId);
                    }

                    // Добавим наклейки к ПК
                    PC dbItemPC = PCRepository.Get(pcId);
                    List<string> stickerList = new List<string>();
                    RequestWorkKindParam stickers = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.StickerNumber).Single();
                    foreach (RequestWorkKindParamSpec spec in stickers.RequestWorkKindParamSpecs)
                    {
                        dbItemPC.Stickers.Add(new PCSticker() { PCId = pcId, StickerNumber = spec.ParamValue });
                        stickerList.Add(spec.ParamValue);
                    }
                    PCRepository.Update(dbItemPC);
                    AddUserHistory_AddStickers(item.Request.UserRegisterId, pcId, stickerList, item.RequestId);
                }
                // Удаление СЗИ в связи с увольнением/декретом
                else if (item.WorkKind.CustomId == (int)WorkKindCode.ScsiDel)
                {
                    string copyNumber = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.CopyNumber).Single().ParamValue;
                    int skziKindId = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.SkziKind).Single().SkziKindId.Value;
                    string deleteReason = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.DeleteReason).Single().ParamValue;

                    var dbItem = UserSkziRepository.GetAll(x => x.SkziKindId == skziKindId && x.CopyNumber == copyNumber).Single();
                    dbItem.DeleteDate = DateTime.Today.Date;
                    dbItem.DeleteReason = deleteReason;
                    dbItem.DeleteSystemUserId = UserPrincipal.UserId;
                    UserSkziRepository.Update(dbItem);
                    AddUserHistory_DelScsi(dbItem.UserSkziId, item.RequestId);
                }
                // Установка ЭП
                // Переустановка ЭП по причине истечения срока  действия
                // Регистрация ЭП
                // Выпуск сертификата
                else if ((item.WorkKind.CustomId == (int)WorkKindCode.CertInstall) || (item.WorkKind.CustomId == (int)WorkKindCode.CertReInstall) || (item.WorkKind.CustomId == (int)WorkKindCode.CertRegister) || (item.WorkKind.CustomId == (int)WorkKindCode.CertCreate))
                {
                    // Запись сертификата в реестр
                    int requestCertId = item.RequestWorkKindParams.Where(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.Cert).Single().RequestCertId.Value;
                    RequestCert requestCert = RequestCertRepository.Get(requestCertId);
                    WriteToCertRegisterFromRequest(requestCert, item.RequestId);
                    /*CertRegister certRegister = new CertRegister();
                    certRegister.UploadDate = DateTime.Now;
                    certRegister.FileName = requestCert.FileName;
                    certRegister.FromDate = requestCert.FromDate;
                    certRegister.ToDate = requestCert.ToDate;
                    certRegister.IdentityCenterId = requestCert.IdentityCenterId;
                    certRegister.SerialNumber = requestCert.SerialNumber;
                    certRegister.SerialNumberEtoken = requestCert.SerialNumberEtoken;
                    certRegister.Thumbprint = requestCert.Thumbprint;
                    certRegister.FileData = requestCert.FileData;
                    certRegister.UserRegisterId = requestCert.UserRegisterId;
                    certRegister.PCId = requestCert.PCId;
                    certRegister.RequestId = item.RequestId;
                    requestCert.RequestCertInfoSystems.ToList().ForEach(x => certRegister.CertRegisterInfoSystems.Add(new CertRegisterInfoSystem() { InfoSystemId = x.InfoSystemId }));
                    CertRegisterRepository.Add(certRegister);
                    AddCertHistory(null, new CertRegisterModel(certRegister), item.RequestId);*/
                }
            }

            return Json(new { success = true });
        }

        [System.Web.Mvc.HttpPost]
        [System.Web.Mvc.Authorize(Roles = "Administrator, UsersReestrSertificateEditor, UsersReestrSkziEditor, UsersReestrSoftwareEditor")]
        public JsonResult FilterAutocomplete(string term)
        {
            var resultList = RequestRepository.GetAll().FilterByFullName( term ).ToAutocompleteItems().ToList();
            
            var searchList2 = RequestRepository.GetAll().Where(x => x.UserRegister.Department.Name.Contains(term)).Select( x => x.UserRegister.Department.Name ).Distinct();
            resultList.AddRange(searchList2.Select(item => new AutocompleteItem { Label = item }));

            return Json(resultList, JsonRequestBehavior.AllowGet);
        }
    }
}
